package code.c03_stackQueue.homework;

import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Scanner;

/**
 * @author thinkpad - 83start
 * @version v1.0
 * @create 2022/9/30 7:42
 * @package code.c02_list.homework
 * @description HDU1873—看病要排队
 * 时间限制：3000ms，空间限制：32768K。（HDU1509与之类似）
 * 问题描述：看病要排队这个是地球人都知道的常识。不过经过细心的0068的观察，他发现了医院里排队还是有讲究的。
 * 0068所去的医院有三个医生同时看病。而看病的人病情有轻重，所以不能根据简单的先来先服务的原则。所以医院对
 * 每种病情规定了10种不同的优先级。级别为10的优先权最高，级别为1的优先权最低。医生在看病时，则会在他的队伍
 * 里面选择一个优先权最高的人进行诊治。如果遇到两个优先权一样的病人的话，则选择最早来排队的病人。
 * 现在就请你帮助医院模拟这个看病过程。
 * 输入格式：输入数据包含多组测试，请处理到文件结束。每组数据第一行有一个正整数n（0<n<2000）表示发生事件
 * 的数目。接下来有n行分别表示发生的事件。一共有两种事件：
 * （1）IN A B：表示有一个拥有优先级B的病人要求医生A诊治（0<A≤3，0<B≤10）。
 * （2）OUT A：表示医生A进行了一次诊治，诊治完毕后，病人出院（0<A≤3）。
 * 输出格式：对于每个“OUT A”事件，请在一行里面输出被诊治人的编号ID。如果该事件时无病人需要诊治，则输出
 * "EMPTY"。诊治人的编号ID的定义为：在一组测试中，“IN A B”事件发生第k次时，进来的病人ID即为k。从1开始编号。
 * <p>
 * 输入示例：
 * 7 IN 1 1 IN 1 2 OUT 1 OUT 2 IN 2 1 OUT 2 OUT 1 2 IN 1 1 OUT 1
 * 输出示例：
 * 2 EMPTY 3 1 1
 */


public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // 创建优先队列
        PriorityQueue[] dockerQueue = new PriorityQueue[4];
        // 需要操作的数量
        int T;
        // 医生的id
        int doctorId;
        // 病人的等级
        int patientLevel;

        // 读取用户从控制台输入的信息
        while (scanner.hasNext()) {
            // 读取第一行：需要操作的数量
            T = scanner.nextInt();
            // 定义三个优先队列，表示三个医生的队伍，cPatient 是病人看病的排队规则
            // 因为输入台输入的医生编号只有1，2，3 ,但是数组的起始位置 是0，所以浪费一个数组的空间
            dockerQueue[1] = new PriorityQueue<>(cPatient);
            dockerQueue[2] = new PriorityQueue<>(cPatient);
            dockerQueue[3] = new PriorityQueue<>(cPatient);
            // 设置一个病人的编号
            int patientId = 1;
            while ((T--) != 0) {
                String op = scanner.next();
                // 判断病人是看病（IN）还是出院（OUT）
                // 如果是IN ，则连续读取两个元素
                if (op.equals("IN")) {
                    // 读取两个数字
                    doctorId = scanner.nextInt();
                    patientLevel = scanner.nextInt();
                    // 将病人添加到医生的队列中去
                    dockerQueue[doctorId].add(new Patient(patientId++, patientLevel));
                } else if (op.equals("OUT")) {
                    doctorId = scanner.nextInt();
                    if (!dockerQueue[doctorId].isEmpty()) { // 如果医生列表不为空，则取队列中的第一个元素
                        Patient patient = (Patient) dockerQueue[doctorId].poll();
                        System.out.println(patient.id);
                    } else { // 否则就输出EMPTY
                        System.out.println("EMPTY");
                    }
                } else {
                    throw new IllegalArgumentException("程序错误");
                }
            }
        }
    }

    // 定义一个病人排序的变量
    static Comparator<Patient> cPatient = new Comparator<Patient>() {
        // 排序规则，当等级不同时候，等级大的优先，当等级相同时，id 小的优先
        @Override
        public int compare(Patient p1, Patient p2) {
            return (p1.level != p2.level) ? (p2.level - p1.level) : (p1.id - p2.id);
        }
    };

}

class Patient implements Comparable {
    // 病人的编号
    int id;

    // 病人的等级
    int level;

    public Patient(int id, int level) {
        this.id = id;
        this.level = level;
    }

    @Override
    public int compareTo(Object o) {
        Patient newPatient = (Patient) o;
        if (newPatient.level != this.level) {
            return newPatient.level - this.level;
        }
        return this.id - newPatient.id;
    }
}
